<?php

class View extends MVCBase
{
    protected $_tplConfig = NULL;
    protected $_block_data = array();

    function __construct($viewName = NULL, $viewBlock = NULL)
    {
        parent::__construct();
        global $_app_config;
        $this->_tplConfig = $_app_config['masterTemplate'];
        if (!is_null($viewName))
        {
            $this->setTplConfig('view_name', $viewName);
            if (is_null($viewBlock))
            {
                $viewBlock = $this->_tplConfig['default_render_block'];
            }
            $this->changeViewBlock($viewBlock);
            if (isset($_app_config['component_enable']) && $_app_config['component_enable'] == TRUE)
            {
                $this->setTplConfig('loadFromComponent', TRUE);
                $templatePath = $viewName . '.html';
                $this->setBlock($viewBlock, $templatePath,FALSE);
            }
            else
                $this->setBlock($viewBlock, $viewName . '.html',TRUE);
            $this->validatePath();
        }
    }

    protected function validatePath()
    {
        global $_app_config;
        $masterPath = APP_PATH . 'templates' . DS . $this->_tplConfig['master'][0];        
        if (!file_exists($masterPath))
        {
            exit('Master template does not exist !');
        }
        if($this->_tplConfig['block'][$this->_tplConfig['view_block']][1] == 'general')
        {
            $tplPath = APP_PATH . 'templates' . DS . $this->_tplConfig['block'][$this->_tplConfig['view_block']][0];
        }
        else
        {
            $tplPath = APP_PATH . 'components' . DS . $_app_config['component_name'] . DS . 'templates' . DS . $this->_tplConfig['block'][$this->_tplConfig['view_block']][0];
        }
        if (!file_exists($tplPath))
        {
            exit('Template name ' . $this->_tplConfig['view_name'] . ' does not exist !');
        }
    }

    public function setBlockData($data, $blockName = NULL)
    {
        if (is_null($blockName))
        {
            if (isset($this->_tplConfig['view_block']))
                $blockName = $this->_tplConfig['view_block'];
            else
                $blockName = $this->_tplConfig['default_render_block'];
        }
        $this->_block_data[$blockName] = $data;
    }

    public function appendBlockData($data, $blockName = NULL)
    {
        if (is_null($blockName))
        {
            if (isset($this->_tplConfig['view_block']))
                $blockName = $this->_tplConfig['view_block'];
            else
                $blockName = $this->_tplConfig['default_render_block'];
        }
        if (isset($this->_block_data[$blockName]))
        {
            if (!is_array($this->_block_data[$blockName]))
            {
                $tmp = $this->_block_data[$blockName];
                $this->_block_data[$blockName] = array();
                $this->_block_data[$blockName]['data'] = $tmp;
            }
        }
        else
        {
            $this->_block_data[$blockName] = array();
        }
        if (is_array($data))
        {
            foreach ($data as $key => $value)
            {
                $this->_block_data[$blockName][$key] = $value;
            }
        }
        else
        {
            if (is_array($this->_block_data[$blockName]['data']))
            {
                array_push($this->_block_data[$blockName]['data'], $data);
            }
            else
            {
                $tmp = $this->_block_data[$blockName]['data'];
                $this->_block_data[$blockName]['data'] = array();
                array_push($this->_block_data[$blockName]['data'], $tmp);
                array_push($this->_block_data[$blockName]['data'], $data);
            }
        }
    }

    public function cleanInputData()
    {
        $this->_block_data = array();
    }

    public function render()
    {        
        $block = array();
        $blockNameArr = array_keys($this->_tplConfig['block']);
        foreach ($blockNameArr as $blockName)
        {
            $block[$blockName] = $this->renderBlock($blockName);
        }
        if (isset($this->_block_data['js']))
            $block['js'] = $this->_block_data['js'];
        if($this->_tplConfig['master'][1] == 'general')
        {
            $path = APP_PATH . 'templates' . DS . $this->_tplConfig['master'][0];
        }
        else
        {
            $path = APP_PATH . 'components' . DS . $_app_config['component_name'] .  $this->_tplConfig['master'][0];
        }
        require $path;
    }

    public function renderBlock($blockName)
    {
        global $_app_config;
        if (isset($this->_block_data[$blockName]))
        {
            if (is_array($this->_block_data[$blockName]))
            {
                foreach ($this->_block_data[$blockName] as $key => $value)
                {
                    $$key = $value;
                }
            }
            else
            {
                $data = $this->_block_data[$blockName];
            }

        }
        else
        {
            $data = null;
        }

        if (is_null($this->_tplConfig['block'][$blockName][0]))
        {
            return $data;
        }
        else
        {
            if($this->_tplConfig['block'][$blockName][1] == 'general')
            {
                $path = APP_PATH . 'templates' . DS . $this->_tplConfig['block'][$blockName][0];
            }
            else
            {
                $path = APP_PATH . 'components' . DS . $_app_config['component_name'] . DS . 'templates' . DS . $this->_tplConfig['block'][$blockName][0];
            }
            
            if (!file_exists($path))
                {
                    exit("Cannot find template at $path");                                        
                }
            ob_start();
            require $path;
            $output = ob_get_contents();
            ob_end_clean();
            return $output;
        }
    }

    public function setBlock($blockName, $templatePath, $isGeneral = TRUE)
    {        
        if($isGeneral)
        {
            $path = array($templatePath,'general');            
        }
        else
        {
            $path = array($templatePath,'component');
        }
        $array = array($blockName => $path);
        $this->setTplConfig('block', $array, FALSE);
    }

    public function changeViewBlock($blockName)
    {
        if (isset($this->_tplConfig['view_block']))
        {
            $tmp = $this->_tplConfig['view_block'];
            if (isset($this->_tplConfig['block'][$tmp]))
            {
                $path = $this->_tplConfig['block'][$tmp];
                $this->setBlock($blockName, $path);
                unset ($this->_tplConfig['block'][$tmp]);
            }
        }
        $this->_tplConfig['view_block'] = $blockName;
    }

    public function addJs($jsName)
    {
        $base_url =  Utility::getSiteUrl();
        if (!is_null($base_url) && strlen($base_url) > 0)
        {
            $scriptPath = $base_url . DS . 'public/js/' . $jsName . '.js';
            $script = "<script type=\"text/javascript\" src=\"$scriptPath\"></script>";
            if (!isset($this->_block_data['js']))
                $this->_block_data['js'] = "";
            $this->_block_data['js'] .= $script . "\n";
        }
    }

    public function setTplConfig($name, $value, $forceReplace = TRUE)
    {
        if (isset($this->_tplConfig[$name]) && !$forceReplace)
        {
            if (!is_array($this->_tplConfig[$name]))
            {
                exit("Error occurs when set config!");
            }
            foreach ($value as $key => $content)
            {
                $this->_tplConfig[$name][$key] = $content;
            }
        }
        else
        {
            $this->_tplConfig[$name] = $value;
        }
    }

    public function getConfig($name)
    {
        if (isset($this->_tplConfig[$name]))
            return $this->_tplConfig[$name];
        else
            return NULL;
    }
}
 
